/**
  * @file       network.h
  * @brief      
  * @copyright  Copyright (c) 2020~2030 ShenZhen Dxtc Tech. Co., Ltd.
  * All rights reserved.
  * @version    V1.0
  * @author     TianXubin
  * @date       2021-11-11 16:38:37
  * @note       鼎新同创·智能锁
  *
  *****************************************************************************/

#ifndef __NETWORK_H__
#define __NETWORK_H__

#include "osal.h"


#pragma pack(1)

/* 固件数据包结构 */
typedef struct
{
    uint16_t psn;      //包编号
    uint16_t data_len; //数据域长度
    uint8_t  data[0];  //数据域
} FirmwareData_t;

/* network组件消息类型（publish） */
typedef struct
{
    uint8_t msg_type;  //消息类型
    union
    {
        uint8_t        devNum;       //当 msg_type == NETWORK_MSG_FW_DL_SUCCESS 有效
        FirmwareData_t fw_data[0];   //当 msg_type == NETWORK_MSG_FW_DATA 有效
        MqttData_t     mqtt_data[0]; //当 msg_type == NETWORK_MSG_MQTT_RECV 有效
    };
} NetworkMsg_t;

#pragma pack()



/**
  * @brief  连接mqtt服务器
  * @note
  * @param  para：mqtt登录信息，该参数是一个结构体指针：MqttConnectInfo_stu_t
  * @retval
  */
#define Network_MqttConnect(para, len)             \
({                                                 \
    uint8_t *temp = OSAL_Malloc(len + 1);          \
    temp[0] = NETWORK_CTRL_MQTT_CONNECT;           \
    memcpy(&temp[1], para, len);                   \
    OSAL_MboxPost(COMP_NETWORK, 0, temp, len + 1); \
    OSAL_Free(temp);                               \
})

/**
  * @brief  断开mqtt连接
  * @note
  * @retval
  */
#define Network_MqttDisconnect()                        \
({                                                      \
    uint8_t temp[2] = {NETWORK_CTRL_MQTT_DISCONNECT, 0};\
    OSAL_MboxPost(COMP_NETWORK, 0, temp, sizeof(temp)); \
})

/**
  * @brief  发送mqtt消息
  * @note
  * @param  topic_len：mqtt主题长度
  * @param  topic：mqtt主题内容
  * @param  payload_len：mqtt消息长度
  * @param  payload：mqtt消息
  * @retval
  */
#define Network_MqttSend(_qos, _topic, _payload, _len)                    \
({                                                                        \
    uint8_t *temp = (uint8_t*)OSAL_Malloc(sizeof(MqttData_t) + _len + 1); \
    MqttData_t *mqtt = (MqttData_t *)(temp + 1);                          \
    memset(temp, 0, sizeof(MqttData_t) + _len + 1);                       \
    temp[0] = NETWORK_CTRL_MQTT_SEND;                                     \
    mqtt->qos = _qos;                                                     \
    strcpy((const char *)mqtt->topic, _topic);                            \
    memcpy(mqtt->payload, _payload, _len);                                \
    mqtt->payload_len = _len;                                             \
    OSAL_MboxPost(COMP_NETWORK, 0, temp, sizeof(MqttData_t) + _len + 1);  \
    OSAL_Free(temp);                                                      \
})

/**
  * @brief  http下载文件
  * @note
  * @param  _devNum：dfu设备号（DFU_DevNum_enum_t中定义）
  * @param  _len：固件长度
  * @param  _md5：固件md5值
  * @param  _url：链接
  * @retval
  */
#define Network_HttpDownload(_devNum, _len, _md5, _url)              \
({                                                                   \
    uint16_t len = sizeof(FmDlParam_stu_t) + (strlen(_url) + 1) + 1; \
    uint8_t *temp = OSAL_Malloc(len);                                \
    FmDlParam_stu_t *pfm = NULL;                                     \
    temp[0] = NETWORK_CTRL_HTTP_DOWNLOAD;                            \
    pfm = (FmDlParam_stu_t*)(&temp[1]);                              \
    pfm->devNum = _devNum;                                           \
    pfm->fileLen = _len;                                             \
    strcpy((char *)pfm->md5, _md5);                                  \
    strcpy((char *)pfm->url, _url);                                  \
    OSAL_MboxPost(COMP_NETWORK, 0, temp, len);                       \
    OSAL_Free(temp);                                                 \
})

/**
  * @brief  获取固件升级数据
  * @note
  * @param  devNum：dfu设备号（DFU_DevNum_enum_t中定义）
  * @param  psn：包编号
  * @param  len：包长度
  * @retval
  */
#define Network_GetDfuData(_devNum, _psn, _len)                      \
({                                                                   \
    uint8_t len = sizeof(FirmwareData_t) + 2;                        \
    uint8_t *temp = OSAL_Malloc(len);                                \
    temp[0] = NETWORK_CTRL_GET_DFU_DATA;                             \
    temp[1] = _devNum;                                               \
    FirmwareData_t *data = (FirmwareData_t *)&temp[2];               \
    data->psn = _psn;                                                \
    data->data_len = _len;                                           \
    OSAL_MboxPost(COMP_NETWORK, 0, temp, len);                       \
    OSAL_Free(temp);                                                 \
})

/**
  * @brief  向驱动层发送esn和password
  * @note   用作更新证书使用
  * @param  Cer_Set_Esn_Pwd结构体
  * @retval
  */
#define Network_Set_Esn_Pwd(para, len)             \
({                                                 \
    uint8_t *temp = OSAL_Malloc(len + 1);          \
    temp[0] = NETWORK_CTRL_SET_ESN_AND_PWD;        \
    memcpy(&temp[1], para, len);                   \
    OSAL_MboxPost(COMP_NETWORK, 0, temp, len + 1); \
    OSAL_Free(temp);                               \
})

#endif
